package cash.cmp.personal_financial_system.controller;

import cash.cmp.personal_financial_system.model.account.Account;
import cash.cmp.personal_financial_system.model.Bill;
import cash.cmp.personal_financial_system.model.Page;
import cash.cmp.personal_financial_system.model.account.Graph;
import cash.cmp.personal_financial_system.model.account.Pie;
import cash.cmp.personal_financial_system.service.impl.BillServiceImpl;
import cash.cmp.personal_financial_system.utils.Result;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/bill")
public class BillController {

    @Autowired
    private BillServiceImpl billService;

    @RequiresRoles("admin")
    @RequestMapping(value = "/findAllBill")
    public Result findAllBill(){
        List<Bill> bills = billService.findAllBill();
        return Result.succ(200,"success",bills);
    }

    @RequestMapping(value = "/findBill")
    public Result findBill(){
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        List<Bill> bills = billService.findBill(account.getId());
        return Result.succ(200,"success",bills);
    }

    @RequestMapping(value = "/findBillByAll")
    public Result findBillByAll( @RequestBody Map<String, String> data) throws ParseException {
        Integer id = null;
        if ( data.get("id") != null){
            id = Integer.parseInt(data.get("id"));
        }
        String start = data.get("startTime");
        String end = data.get("endTime");
        String type = null;
        String bigType = null;
        int page = Integer.parseInt(data.get("page"));
        int pageSize = Integer.parseInt(data.get("pageSize"));
        String Type = data.get("Type");

        if(billService.isBigType(Type)) {
            bigType = Type;
        }else{
            type = Type;
        }

        Date startTime = null;
        Date endTime = null;
        if(start != null) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            startTime = dateFormat.parse(start);
        }
        if(end != null){
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            endTime = dateFormat.parse(end);
        }

        List<Bill> bills;
        bills = billService.findBillByAll(id, startTime, endTime, type, bigType,page,pageSize);
        int total = billService.countByAll(id, startTime, endTime, type, bigType);
        Page<Bill> pageObject = new Page<>();
        pageObject.setData(bills);
        pageObject.setPage(page);
        pageObject.setTotal(total);
        return Result.succ(200,"success",pageObject);
    }
    @RequestMapping(value = "/sumByApp")
    public Result sumByApp( @RequestBody Map<String, String> data) throws ParseException {
        Integer id = null;
        if ( data.get("id") != null){
            id = Integer.parseInt(data.get("id"));
        }
        Integer relatedId = null;
        if ( data.get("relatedId") != null){
            relatedId = Integer.parseInt(data.get("relatedId"));
        }

        String start = data.get("startTime");
        String end = data.get("endTime");

        Date startTime = null;
        Date endTime = null;
        if(start != null) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            startTime = dateFormat.parse(start);
        }
        if(end != null){
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            endTime = dateFormat.parse(end);
        }
        Map<Integer, Double> tmp = billService.sumByApp(startTime, endTime, id, relatedId);
        return Result.succ(200,"success",tmp);
    }


    @RequestMapping(value = "/findBillByApp")
    public Result findBillByApp( @RequestBody Map<String, String> data) throws ParseException {
        Integer id = null;
        if ( data.get("id") != null){
            id = Integer.parseInt(data.get("id"));
        }
        Integer relatedId = null;
        if ( data.get("relatedId") != null){
            relatedId = Integer.parseInt(data.get("relatedId"));
        }
        String start = data.get("startTime");
        String end = data.get("endTime");
        int page = Integer.parseInt(data.get("page"));
        int pageSize = Integer.parseInt(data.get("pageSize"));

        Date startTime = null;
        Date endTime = null;
        if(start != null) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            startTime = dateFormat.parse(start);
        }
        if(end != null){
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            endTime = dateFormat.parse(end);
        }

        List<Bill> bills;
        bills = billService.findBillByApp(id, relatedId, startTime, endTime, page,pageSize);
        int total = billService.countByApp(id, relatedId, startTime, endTime);
        Page<Bill> pageObject = new Page<>();
        pageObject.setData(bills);
        pageObject.setPage(page);
        pageObject.setTotal(total);
        return Result.succ(200,"success",pageObject);
    }

    @RequestMapping(value = "/billByGraph")
    public Result billByGraph( @RequestBody Map<String, String> data) throws ParseException {
        Integer id = null;
        if ( data.get("id") != null){
            id = Integer.parseInt(data.get("id"));
        }
        Integer relatedId = null;
        if ( data.get("relatedId") != null){
            relatedId = Integer.parseInt(data.get("relatedId"));
        }
        String end = data.get("endTime");
        String Start = data.get("startTime");
        Date startTime = null;
        Date endTime = null;
        if(Start != null){
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            startTime = dateFormat.parse(Start);
        }
        if(end != null){
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            endTime = dateFormat.parse(end);
        }

        String type = data.get("type");

        // 结果是个list
        List<Object> list = new ArrayList<>();
        // list1, 收入，支出的统计； list2, 柱状图使用的数据； list3, 饼状图使用的数据；
        Map<Integer, Double> list1;
        List<Graph[]> list2 = null;
        List<Map<String, Double>> list3;

        //  收入，支出的统计
        list1 = billService.sumByApp(startTime, endTime, id, relatedId);
//        System.out.println("list1 : " + list1);
        // 2.1、获取七天的动态数据
        if("1".equals(type)){
            list2 = billService.BillByGraph1(id,relatedId,startTime,endTime);
        }
        // 2.2、获取一个月内的动态数据
        if("2".equals(type)){
            list2 = billService.BillByGraph2(id,relatedId,startTime,endTime);
        }
        // 2.3、获取一年月内的动态数据
        if("3".equals(type)){
            list2 = billService.BillByGraph3(id,relatedId,startTime,endTime);
        }
//        System.out.println("list : ");
//        int i =0;
//        for (Graph[] graphs: list2) {
//            System.out.print("graphs" + i + " : " + Arrays.toString(graphs));
//            i++;
//        }
        // 3、饼状图的数据获取
        list3 = billService.BillByPie(id, relatedId, startTime, endTime);
//        int i = 0;
//        System.out.println("list3 : ");
//        for (Map<String, Double> map:list3) {
//            System.out.println("map" + i + " : " + map);
//        }

        list.add(list1);
        list.add(list2);
        list.add(list3);

        return Result.succ(200,"success",list);
    }

    @RequestMapping(value = "/searchBillByApp")
    public Result searchBillByApp( @RequestBody Map<String, String> data) throws ParseException {
        Integer id = null;
        if ( data.get("id") != null){
            id = Integer.parseInt(data.get("id"));
        }
        Integer relatedId = null;
        if ( data.get("relatedId") != null){
            relatedId = Integer.parseInt(data.get("relatedId"));
        }
        int page = Integer.parseInt(data.get("page"));
        int pageSize = Integer.parseInt(data.get("pageSize"));

        String like = data.get("like");
        if(like == null || "".equals(like)) {
            return Result.fail(493,"fail","请输入搜寻内容");
        }
        Double money = null;
        try{
            money = Double.parseDouble(like);
            like = null;
        }catch (Exception ignored) {
        }

        List<Bill> bills;
        bills = billService.searchByApp(id, relatedId, money,like, page, pageSize);
        int total = billService.countSearchByApp(id,relatedId, money,like);
        Page<Bill> pageObject = new Page<>();
        pageObject.setData(bills);
        pageObject.setPage(page);
        pageObject.setTotal(total);
        return Result.succ(200,"success",pageObject);
    }

    @RequiresRoles("admin")
    @RequestMapping(value = "/findBillByPage")
    public Result findBillByPage(@RequestBody Map<String, Integer> data){
        int page = data.get("page");

        int total = billService.billCount();

        Page<Bill> pageObject = new Page<>();
        if (data.get("pageSize") != null) {
            pageObject.setPageSize(data.get("pageSize"));
        }
        List<Bill> bills = billService.findBillByPage(page,pageObject.getPageSize());
        pageObject.setData(bills);
        pageObject.setPage(page);
        pageObject.setTotal(total);

        return Result.succ(200,"success",pageObject);
    }

    @RequestMapping(value = "/findBillByPageId")
    public Result findBillByPageId(@RequestBody Map<String, Integer> data){
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        int page = data.get("page");

        int total = billService.billCountById(account.getId());

        Page<Bill> pageObject = new Page<>();
        if (data.get("pageSize") != null) {
            pageObject.setPageSize(data.get("pageSize"));
        }
        List<Bill> bills = billService.findBillByPageId(page,pageObject.getPageSize(),account.getId());
        pageObject.setData(bills);
        pageObject.setPage(page);
        pageObject.setTotal(total);

        return Result.succ(200,"success",pageObject);
    }

    @RequestMapping(value = "/updateBill")
    public Result updateBill(@RequestBody Bill bill){
        Boolean flag = billService.updateBill(bill);
        if(!flag){
            return Result.fail("修改失败");
        }
        return Result.succ(200,"success",null);
    }

    @RequestMapping(value = "/insertBill")
    public Result insertBill(@RequestBody Bill bill){
        // setId
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        bill.setId(account.getId());

        // set Time、 billId
        Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
        String billId = bill.getId() + "," +  ft.format(dNow);
        bill.setBillId(billId);
        bill.setInsertionTime(dNow);
        if(bill.getTime() == null){
            bill.setTime(dNow);
        }
        Boolean flag = billService.insertBill(bill);
        if( !flag ){
            return Result.fail("插入失败");
        }
        return Result.succ(200,"success",null);
    }


    //管理员添加账单
    @RequiresRoles("admin")
    @RequestMapping(value = "/adminInsertBill")
    public Result adminInsertBill(@RequestBody Bill bill){
        // set Time、 billId
        Date dNow = new Date( );
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
        String billId = bill.getId() + "," +  ft.format(dNow);
        bill.setBillId(billId);
        bill.setInsertionTime(dNow);
        if(bill.getTime() == null){
            bill.setTime(dNow);
        }
        Boolean flag = billService.insertBill(bill);
        if( !flag ){
            return Result.fail("插入失败");
        }
        return Result.succ(200,"success",null);
    }

    @RequestMapping(value = "/deleteBill")
    public Result deleteBill(@RequestBody Map<String,String> data) {
        System.out.println(data.get("billId"));
        Boolean flag = billService.deleteBill(data.get("billId"));
        if(!flag){
            return Result.fail("删除失败");
        }
        return Result.succ(200,"success",null);
    }

    @RequestMapping(value = "/deleteBillById")
    public Result deleteBillById(@RequestBody Map<String,String> data){
        int id = Integer.parseInt(data.get("id"));
        Boolean flag = billService.deleteBillById(id);
        if(!flag) {
            return Result.fail("删除失败");
        }
        return Result.succ(200,"success",null);
    }
}
